﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VTWEB.ServiceReference1;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using System.Threading;
using System.Globalization;

namespace VTWEB
{


    public partial class MainPage : UserControl
    {

        private System.Windows.Threading.DispatcherTimer myDispatcherTimer;
        XDocument doc;
        Int32 tickCounter = 0;
        List<Player> playersA;
        Team teamA;
        int ticksPerTime;
        List<Player> playersB;
        Team teamB;
        List<Score> scoreA = new List<Score>();
        List<Score> scoreB = new List<Score>();
        NumberFormatInfo formatInfo = new NumberFormatInfo();
        List<Score> totalScore = new List<Score>();

        public MainPage()
        {
            InitializeComponent();
            formatInfo.NumberDecimalSeparator = ".";

        }


        private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.playerName.IsChecked == true)
            {
                this.infoTeam1Player1.Text = teamA.Players[0].Name;
                this.infoTeam1Player2.Text = teamA.Players[1].Name;
                this.infoTeam1Player3.Text = teamA.Players[2].Name;
                this.infoTeam1Player4.Text = teamA.Players[3].Name;
                this.infoTeam1Player5.Text = teamA.Players[4].Name;
                this.infoTeam2Player1.Text = teamB.Players[0].Name;
                this.infoTeam2Player2.Text = teamB.Players[1].Name;
                this.infoTeam2Player3.Text = teamB.Players[2].Name;
                this.infoTeam2Player4.Text = teamB.Players[3].Name;
                this.infoTeam2Player5.Text = teamB.Players[4].Name;
            }
            else if (this.playerNumber.IsChecked == true)
            {
                this.infoTeam1Player1.Text = Convert.ToString(teamA.Players[0].Id);
                this.infoTeam1Player2.Text = Convert.ToString(teamA.Players[1].Id);
                this.infoTeam1Player3.Text = Convert.ToString(teamA.Players[2].Id);
                this.infoTeam1Player4.Text = Convert.ToString(teamA.Players[3].Id);
                this.infoTeam1Player5.Text = Convert.ToString(teamA.Players[4].Id);
                this.infoTeam2Player1.Text = Convert.ToString(teamB.Players[0].Id);
                this.infoTeam2Player2.Text = Convert.ToString(teamB.Players[1].Id);
                this.infoTeam2Player3.Text = Convert.ToString(teamB.Players[2].Id);
                this.infoTeam2Player4.Text = Convert.ToString(teamB.Players[3].Id);
                this.infoTeam2Player5.Text = Convert.ToString(teamB.Players[4].Id);
            }
            else if (this.none.IsChecked == true)
            {
                this.infoTeam1Player1.Text = "";
                this.infoTeam1Player2.Text = "";
                this.infoTeam1Player3.Text = "";
                this.infoTeam1Player4.Text = "";
                this.infoTeam1Player5.Text = "";
                this.infoTeam2Player1.Text = "";
                this.infoTeam2Player2.Text = "";
                this.infoTeam2Player3.Text = "";
                this.infoTeam2Player4.Text = "";
                this.infoTeam2Player5.Text = "";
            }
        }

        private void client_GetXmlStringCompleted(object sender, GetXmlStringCompletedEventArgs e)
        {
            TextReader reader = new StringReader(e.Result);
            doc = XDocument.Load(reader);

            teamA = new Team();
            playersA = new List<Player>();

            var players = from equipoNode in doc.Root.Elements("equipo")
                          from jugadorNode in equipoNode.Descendants("jugador")
                          where equipoNode.Attribute("id").Value == "A"
                          select new { TeamName = equipoNode.Attribute("nombre").Value, PlayerName = jugadorNode.Value, PlayerId = Int32.Parse(jugadorNode.Attribute("nro").Value) };
            foreach (var player in players)
            {
                if (teamA.Name == null)
                    teamA.Name = player.TeamName;
                playersA.Add(new Player() { Id = player.PlayerId, Name = player.PlayerName });
            }
            teamA.Players = playersA.ToArray();

            teamB = new Team();
            playersB = new List<Player>();

            var morePlayers = from equipoNode in doc.Root.Elements("equipo")
                              from jugadorNode in equipoNode.Descendants("jugador")
                              where equipoNode.Attribute("id").Value == "B"
                              select new { TeamName = equipoNode.Attribute("nombre").Value, PlayerName = jugadorNode.Value, PlayerId = Int32.Parse(jugadorNode.Attribute("nro").Value) };
            foreach (var player in morePlayers)
            {
                if (teamB.Name == null)
                    teamB.Name = player.TeamName;
                playersB.Add(new Player() { Id = player.PlayerId, Name = player.PlayerName });
            }
            teamB.Players = playersB.ToArray();


            ticksPerTime = Int32.Parse(doc.Root.Attribute(XName.Get("ticksPorTiempo")).Value);

            team1.Text = "Equipo Local: " + teamA.Name;
            team2.Text = "Equipo Visitante: " + teamB.Name;



            myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000); // 100 Milliseconds 
            myDispatcherTimer.Tick += new EventHandler(Each_Tick);
            myDispatcherTimer.Start();
        }
        Int32 tickSecondTime = 0;
        // Fires every 1000 miliseconds while the DispatcherTimer is active.
        public void Each_Tick(object o, EventArgs sender)
        {/*Aca ponemos el movimiento de cada jugador en un tick */

            double factor = 20f;

            if (tickCounter < ticksPerTime)
            {
                Faults("primertiempo", tickCounter);
                YellowCards("primertiempo", tickCounter);
                RedCards(tickCounter, "primertiempo");
                Scores(tickCounter, "primertiempo");
                BallPositions(factor, "primertiempo", tickCounter);
                TeamAPositions(factor, "primertiempo", tickCounter);
                TeamBPositions(factor, "primertiempo", tickCounter);

                if ((tickCounter * 45 / ticksPerTime) < 90)
                {
                    time.Text = "Tiempo Total: " + tickCounter * 45 / ticksPerTime;
                }
                tickCounter++;
            }
            else
            {
                Faults("segundotiempo", tickSecondTime);
                YellowCards("segundotiempo", tickSecondTime);
                RedCards(tickSecondTime,"segundotiempo" );
                Scores(tickSecondTime, "segundotiempo");
                BallPositions(factor, "segundotiempo", tickSecondTime);
                TeamAPositions(factor, "segundotiempo", tickSecondTime);
                TeamBPositions(factor, "segundotiempo", tickSecondTime);

                if ((tickCounter * 45 / ticksPerTime) < 90)
                {
                    time.Text = "Tiempo Total: " + tickCounter * 45 / ticksPerTime;
                    secondTime.Text = "Tiempo: " + ((tickCounter * 45 / ticksPerTime) - 45);

                }
                else
                {
                    myDispatcherTimer.Stop();
                    time.Text = "Tiempo Total: " + 90;
                    secondTime.Text = "Tiempo: " + 45;
                    String pointsA;
                    if (scoreA.Count == 1)
                    {
                        pointsA = "gol";
                    }
                    else pointsA = "goles";

                    String pointsB;
                    if (scoreB.Count == 1)
                    {
                        pointsB = "gol";
                    }
                    else pointsB = "goles";

                    if (scoreA.Count > scoreB.Count)
                    {
                        winner.Text = "Ganador: " + teamA.Name + " " + scoreA.Count + " " + pointsA;
                        looser.Text = "Perdedor: " + teamB.Name + " " + scoreB.Count + " " + pointsB;

                    }
                    else if (scoreB.Count > scoreA.Count)
                    {
                        winner.Text = "Ganador: " + teamB.Name + " " + scoreB.Count + " " + pointsB;
                        looser.Text = "Perdedor: " + teamA.Name + " " + scoreA.Count + " " + pointsA;
                    }
                    else
                    {
                        winner.Text = "Empate entre " + teamA.Name + " y " + teamB.Name;
                    }
                }
                secondTimeTitle.Text = "Segundo Tiempo";
                tickSecondTime++;
                tickCounter++;
            }

        }

        private void BallPositions(double factor, String time, Int32 tickCounter)
        {


            var ballPositions = from match in doc.Descendants(time)
                                from tickNode in doc.Descendants("tick")
                                from ballNode in tickNode.Descendants("pelota")
                                where
                                   tickNode.Attribute("nro").Value == tickCounter.ToString()
                                select new
                                {
                                    XPosition = Double.Parse(ballNode.Descendants("x").First().Value, formatInfo),
                                    YPosition = Double.Parse(ballNode.Descendants("y").First().Value, formatInfo),
                                };
            foreach (var ballPosition in ballPositions)
            {
                Canvas ball = (Canvas)this.canvaBall;
                ball.SetValue(Canvas.LeftProperty, ballPosition.XPosition * factor);
                ball.SetValue(Canvas.TopProperty, ballPosition.YPosition * factor);
            }
        }

        private void TeamBPositions(double factor, String time, Int32 tickCounter)
        {
            var teamBPositions = from match in doc.Descendants(time)
                                 from tickNode in doc.Descendants("tick")
                                 from teamNode in tickNode.Descendants("equipo")
                                 from playerNode in teamNode.Descendants("jugador")
                                 where
                                     tickNode.Attribute("nro").Value == tickCounter.ToString()
                                     && teamNode.Attribute("id").Value == "B"
                                 select new
                                 {
                                     PlayerId = Int32.Parse(playerNode.Attribute("nro").Value),
                                     XPosition = Double.Parse(playerNode.Descendants("x").First().Value, formatInfo),
                                     YPosition = Double.Parse(playerNode.Descendants("y").First().Value, formatInfo),
                                 };

            foreach (var teamBPosition in teamBPositions)
            {
                Canvas canvas = (Canvas)this.FindName("canvaTeam2Player" + teamBPosition.PlayerId.ToString());
                canvas.SetValue(Canvas.LeftProperty, teamBPosition.XPosition * factor);
                canvas.SetValue(Canvas.TopProperty, teamBPosition.YPosition * factor);
            }
        }

        private void TeamAPositions(double factor, String time, Int32 tickCounter)
        {
            var teamAPositions = from match in doc.Descendants(time)
                                 from tickNode in doc.Descendants("tick")
                                 from teamNode in tickNode.Descendants("equipo")
                                 from playerNode in teamNode.Descendants("jugador")
                                 where
                                    tickNode.Attribute("nro").Value == tickCounter.ToString()
                                    && teamNode.Attribute("id").Value == "A"
                                 select new
                                 {
                                     PlayerId = Int32.Parse(playerNode.Attribute("nro").Value),
                                     XPosition = Double.Parse(playerNode.Descendants("x").First().Value, formatInfo),
                                     YPosition = Double.Parse(playerNode.Descendants("y").First().Value, formatInfo),
                                 };

            foreach (var teamAPosition in teamAPositions)
            {
                Canvas canvas = (Canvas)this.FindName("canvaTeam1Player" + teamAPosition.PlayerId.ToString());
                canvas.SetValue(Canvas.LeftProperty, teamAPosition.XPosition * factor);
                canvas.SetValue(Canvas.TopProperty, teamAPosition.YPosition * factor);
            }
        }

        private void Scores(Int32 tickTimer, String time)
        {
            var score = from ticknodeWithGoal in
                            (from tickNode in doc.Root.Element(time).Elements()
                             where tickNode.Attribute("nro").Value == tickTimer.ToString() && tickNode.Elements("gol").Count() == 1
                             select tickNode)
                        select new
                        {
                            Team = ticknodeWithGoal.Element(XName.Get("gol")).Attribute("idEquipo").Value,
                            Player = Int32.Parse(ticknodeWithGoal.Element(XName.Get("gol")).Attribute(XName.Get("nro")).Value),
                        };

            foreach (var scorePosition in score)
            {
                if (scorePosition.Team.Equals("A"))
                {
                    this.infoFault.Text = "Gol de " + teamA.Players[scorePosition.Player - 1].Name + " para " + teamA.Name;
                    this.infoCard.Text = "A los " + (tickCounter * 45 / ticksPerTime).ToString() + " min.";
                    scoreA.Add(new Score() { Id = scorePosition.Player, Name = scorePosition.Team });
                    this.scoreBColor.Visibility = Visibility.Collapsed;
                    this.scoreAColor.Visibility = Visibility.Visible;
                }
                else
                {
                    this.infoFault.Text = "Gol de " + teamB.Players[scorePosition.Player - 1].Name + " para " + teamB.Name;
                    this.infoCard.Text = "A los " + (tickCounter * 45 / ticksPerTime).ToString() + " min.";
                    scoreB.Add(new Score() { Id = scorePosition.Player, Name = scorePosition.Team });
                    this.scoreAColor.Visibility = Visibility.Collapsed;
                    this.scoreBColor.Visibility = Visibility.Visible;
                }
                this.redCardColor.Visibility = Visibility.Collapsed;
                this.yellowCardColor.Visibility = Visibility.Collapsed;
            }
        }

        private void ScoresSecondTime(Int32 tickTimer)
        {
            var score = from match in doc.Descendants("segundotiempo")
                        from tickNode in doc.Descendants("tick")
                        from scoreNode in tickNode.Descendants("gol")
                        where
                           tickNode.Attribute("nro").Value == tickTimer.ToString()
                        select new
                        {
                            Team = scoreNode.Attribute("idEquipo").Value,
                            Player = Int32.Parse(scoreNode.Attribute(XName.Get("nro")).Value),
                        };

            foreach (var scorePosition in score)
            {
                if (scorePosition.Team.Equals("A"))
                {
                    this.infoFault.Text = "Gol de " + teamA.Players[scorePosition.Player - 1].Name + " para " + teamA.Name;
                    this.infoCard.Text = "A los " + (tickCounter * 45 / ticksPerTime).ToString() + " min.";
                    scoreA.Add(new Score() { Id = scorePosition.Player, Name = scorePosition.Team });
                    this.scoreBColor.Visibility = Visibility.Collapsed;
                    this.scoreAColor.Visibility = Visibility.Visible;
                }
                else
                {
                    this.infoFault.Text = "Gol de " + teamB.Players[scorePosition.Player - 1].Name + " para " + teamB.Name;
                    this.infoCard.Text = "A los " + (tickCounter * 45 / ticksPerTime).ToString() + " min.";
                    scoreB.Add(new Score() { Id = scorePosition.Player, Name = scorePosition.Team });
                    this.scoreAColor.Visibility = Visibility.Collapsed;
                    this.scoreBColor.Visibility = Visibility.Visible;
                }
                this.redCardColor.Visibility = Visibility.Collapsed;
                this.yellowCardColor.Visibility = Visibility.Collapsed;
            }
        }

        private void RedCards(Int32 tickTimer, String time)
        {
            var redCard = from ticknodeWithRedCard in
                            (from tickNode in doc.Root.Element(time).Elements()
                             where tickNode.Attribute("nro").Value == tickTimer.ToString() && tickNode.Elements("roja").Count() == 1
                             select tickNode)
                        select new
                        {
                            Team = ticknodeWithRedCard.Element(XName.Get("roja")).Attribute("idEquipo").Value,
                            Player = Int32.Parse(ticknodeWithRedCard.Element(XName.Get("roja")).Attribute(XName.Get("nro")).Value),
                        };
            foreach (var redCardPosition in redCard)
            {
                if (redCardPosition.Team.Equals("A"))
                {
                    this.infoCard.Text = "Tarjeta roja a " + teamA.Players[redCardPosition.Player - 1].Name + " del " + teamA.Name;
                }
                else
                {
                    this.infoCard.Text = "Tarjeta roja " + teamB.Players[redCardPosition.Player - 1].Name + " del " + teamB.Name;
                }
                this.redCardColor.Visibility = Visibility.Visible;
                this.scoreBColor.Visibility = Visibility.Collapsed;
                this.scoreAColor.Visibility = Visibility.Collapsed;
            }
        }

        private void YellowCards(String time, Int32 tickTimer)
        {

            var yellowCard = from ticknodeWithYellowCard in
                            (from tickNode in doc.Root.Element(time).Elements()
                             where tickNode.Attribute("nro").Value == tickTimer.ToString() && tickNode.Elements("amarilla").Count() == 1
                             select tickNode)
                        select new
                        {
                            Team = ticknodeWithYellowCard.Element(XName.Get("amarilla")).Attribute("idEquipo").Value,
                            Player = Int32.Parse(ticknodeWithYellowCard.Element(XName.Get("amarilla")).Attribute(XName.Get("nro")).Value),
                        };
            foreach (var yellowCardPosition in yellowCard)
            {
                if (yellowCardPosition.Team.Equals("A"))
                {
                    this.infoCard.Text = "Tarjeta amarilla a " + teamA.Players[yellowCardPosition.Player - 1].Name + " del " + teamA.Name;
                }
                else
                {
                    this.infoCard.Text = "Tarjeta amarilla a " + teamB.Players[yellowCardPosition.Player - 1].Name + " del " + teamB.Name;
                }
                this.yellowCardColor.Visibility = Visibility.Visible;
                this.scoreBColor.Visibility = Visibility.Collapsed;
                this.scoreAColor.Visibility = Visibility.Collapsed;
            }
        }

        private void stop_Click(object sender, RoutedEventArgs e)
        {
            time.Text = "Tiempo Total: " + tickCounter * 45 / ticksPerTime;
            Int32 secondPeriod = (tickCounter * 45 / ticksPerTime) - 45;
            if (secondPeriod > 45)
            {
                secondTimeTitle.Text = "Segundo Tiempo";
                secondTime.Text = "Tiempo: " + secondPeriod;

            }

            if (myDispatcherTimer.IsEnabled)
            {
                myDispatcherTimer.Stop();
            }

        }

        private void pause_Click(object sender, RoutedEventArgs e)
        {
            if (myDispatcherTimer.IsEnabled)
            {

                time.Text = "Tiempo Total: " + tickCounter * 45 / ticksPerTime;
                Int32 secondPeriod = (tickCounter * 45 / ticksPerTime) - 45;
                if (secondPeriod > 0)
                {
                    secondTimeTitle.Text = "Segundo Tiempo";
                    secondTime.Text = "Tiempo: " + secondPeriod;
                    start.Content = "Continuar";
                }
                myDispatcherTimer.Stop();
            }
        }
        private void start_Click(object sender, RoutedEventArgs e)
        {
            WebService1SoapClient client = new WebService1SoapClient("WebService1Soap");
            client.GetXmlStringCompleted += new EventHandler<GetXmlStringCompletedEventArgs>(client_GetXmlStringCompleted);
            client.GetXmlStringAsync();
            start.Content = "Comenzar";
        }

        private void RadioButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.playerName.IsChecked == true)
                playerInfo.Text = "Seleccione jugador...";
            else if (playerNumber.IsChecked == true)
                playerInfo.Text = "Seleccione jugador...";
            else if (none.IsChecked == true)
                playerInfo.Text = "Seleccione opción...";
            else
                playerInfo.Text = "Seleccione opción...";

        }

        private void courtCanvas_Loaded(object sender, RoutedEventArgs e)
        {
            team1.Text = "Equipo Local: ...";
            team2.Text = "Equipo Visitante: ...";
            time.Text = "Tiempo Total: 0:00";
            secondTime.Text = "";
            secondTimeTitle.Text = "";


        }

        private void Faults(String time, Int32 tickCounter)
        {

            var fault = from match in doc.Descendants(time)
                        from tickNode in doc.Descendants("tick")
                        from faultNode in tickNode.Descendants("falta")
                        where
                           tickNode.Attribute("nro").Value == tickCounter.ToString()
                        select new
                        {
                            Team = faultNode.Attribute("idEquipo").Value,
                            Player = Int32.Parse(faultNode.Attribute(XName.Get("nro")).Value),
                        };

            foreach (var faultPosition in fault)
            {
                if (faultPosition.Team.Equals("A"))
                {
                    this.infoFault.Text = "Ocurrio una falta del jugador Nº " + faultPosition.Player + " del equipo " + teamA.Name;
                }
                else
                {
                    this.infoFault.Text = "Ocurrio una falta del jugador Nº " + faultPosition.Player + " del equipo " + teamB.Name;
                }

            }
        }

        private class Team
        {
            public string Name { get; set; }
            public Player[] Players { get; set; }
        }

        private class Player
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        private class Score
        {
            public int Id { get; set; }
            public string Name { get; set; }

        }

    }




}


